
#ifndef __{{clazz['name']}}_vararg_method__
#define __{{clazz['name']}}_vararg_method__

#include <godot_cpp/classes/object.hpp>
#include <godot_cpp/core/binder_common.hpp>
#include <godot_cpp/variant/builtin_types.hpp>
#include <godot_cpp/variant/variant.hpp>
#include <vector>
{%- for den in dependency %}
	{%- if den == 'class_db' %}
#include <godot_cpp/classes/class_db_singleton.hpp>
	{%- else %}
#include <godot_cpp/classes/{{den}}.hpp>
	{%- endif %}
{%- endfor %}

{%- macro return_type(ret) -%}
	{%- if ret -%}
{{ret}}
	{%- else -%}
void
	{%- endif -%}
{%- endmacro %}

using namespace godot;

{%- set class_name = clazz['name'] %}
{% set vararg_methods = clazz['methods'] | selectattr('is_vararg', 'equalto', true) | list %}

{%- for method in vararg_methods %}
static {{return_type(method['return_type'])}} js_{{method['name']}}_internal(void *opaque, const Variant **p_args, GDExtensionInt p_arg_count) {
	static StringName _gde_name("{{method['name']}}");
	static GDExtensionPtrBuiltInMethod method_{{method['name']}} = internal::gdextension_interface_variant_get_ptr_builtin_method(GDEXTENSION_VARIANT_TYPE_SIGNAL, _gde_name._native_ptr(), {{method['hash']}});
	{%- if method['return_type'] %}
	{{method['return_type']}} ret;
	method_{{method['name']}}(opaque, reinterpret_cast<GDExtensionConstTypePtr *>(p_args), &ret, p_arg_count);
	return ret;
	{%- else %}
	method_{{method['name']}}(opaque, reinterpret_cast<GDExtensionConstTypePtr *>(p_args), nullptr, p_arg_count);
	{%- endif %}
}
{%- endfor %}

{%- for method in vararg_methods %}
{{return_type(method['return_type'])}} js_{{method['name']}}(void *opaque, {{connect_mutable_args(method['arguments'])}}) {
	std::vector<Variant> variant_args;
	std::vector<Variant *> variant_args_ptr;
	{%- for arg in method['arguments'] %}
	variant_args.push_back(p_{{arg['name']}});
	{%- endfor %}
	for (int i = 0; i < p_args.size(); i++) {
		variant_args.push_back(p_args[i]);
	}	
	for (int i = 0; i < variant_args.size(); i++) {
		variant_args_ptr.push_back(&variant_args[i]);
	}
	{%- if method['return_type'] %}
	return js_{{method['name']}}_internal(opaque, const_cast<const Variant **>(variant_args_ptr.data()), variant_args_ptr.size());
	{%- else %}
	js_{{method['name']}}_internal(opaque, const_cast<const Variant **>(variant_args_ptr.data()), variant_args_ptr.size());
	{%- endif %}
}
{%- endfor %}

#endif // __{{clazz['name']}}_vararg_method__